package com.zq.api.task;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.zq.server.admin.dao.SysNotifyMapper;
import com.zq.server.admin.domain.SysNotify;
import com.zq.server.api.dao.ActivityMapper;
import com.zq.server.api.domain.entity.ApiActivity;
import com.zq.server.core.sevcice.WebSocketServer;

import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;


/**
 * 消息推送
 * @author 财哥
 * &#064;  2024.3.28 19:20
 **/
@Component
@Slf4j
@Api(tags = "消息推送")
public class NotifyTask {
    @Autowired
    private ActivityMapper activityMapper;

    @Autowired
    private WebSocketServer socketServer;

    @Autowired
    private SysNotifyMapper notifyService;

    /**
     * 活动发车前两小时进行消息推送
     *
     * 活动发车进行消息推送
     *
     * 活动结束进行消息推送
     */
    @Scheduled(cron = " 0 */30 * * * ? ")
    public void activityTaskAndTimeNotify() {
        log.info("活动消息推送");
        List<ApiActivity> responseList = activityMapper.findTodayActivityList();
        // 空指针检查
        if (responseList == null || responseList.isEmpty()) {
            log.warn("响应列表为空。跳过通知任务。");
            return;
        }
        for (ApiActivity activity : responseList) {
            // 检查活动是否为空
            if (activity == null) {
                log.warn("响应中的活动为空。跳过通知任务。");
                continue;
            }
            if (isWithinThirtyMinutesAfterTwoHoursAgo(activity.getAStarttime())) {
                // 发送开始前两小时的消息通知
                List<Long> playUserIds = activityMapper.getPlayUserIds(activity.getId());
                if (playUserIds.isEmpty()) {
                    log.warn("未找到活动ID为{}的玩家ID。", activity.getId());
                    continue;
                }
                String message = "您报名的" + activity.getATitle() + "活动将在两小时后开始，请准时参加，若活动未举办请及时联系客服。";
                builderSystemActivityNotify(playUserIds, message);
            } else if (isNowEnd(activity.getAEndtime())) {
                // 发送活动开始的消息通知
                List<Long> playUserIds = activityMapper.getPlayUserIds(activity.getId());
                if (playUserIds.isEmpty()) {
                    log.warn("未找到活动ID为{}的玩家ID。", activity.getId());
                    continue;
                }
                String message = "您报名的" + activity.getATitle() + "活动已经结束，活动费用将在活动结束24小时后支付给举办方，若活动未举办请及时联系客服。";
                builderSystemActivityNotify(playUserIds, message);
            }
        }
    }

    /**
     * 消息推送构建
     * @author 财哥
     * @date 2024.3.28 18:43
     * @param userIds
     * @param message
     **/
    private void builderSystemActivityNotify(List<Long> userIds, String message) {
        List<SysNotify> sysNotifyList = new ArrayList<>();
        SysNotify sysNotify = null;
        for (Long userId : userIds) {
            sysNotify = new SysNotify();
            sysNotify.setSendTime(LocalDateTime.now());
            sysNotify.setMessage(message);
            sysNotify.setTargetId(userId);
            sysNotify.setType(1);
            sysNotify.setTargetType(1);
            sysNotifyList.add(sysNotify);
//            try {
//                socketServer.sendToOne(userId.toString(), JSONObject.toJSONString(sysNotify));
//            } catch (BaseException e) {
//                log.error("向用户ID{}发送通知失败。", userId, e);
//            }
        }
        notifyService.batchInsertNotify(sysNotifyList);
    }
    // 判断指定时间是否在当前时间的两小时前并且在这个时间点到当前时间的30分钟范围内
    public boolean isWithinThirtyMinutesAfterTwoHoursAgo(LocalDateTime specifiedTime) {
        // 获取当前时间的两小时前的时间点
        LocalDateTime twoHoursAgo = LocalDateTime.now().minusHours(2);
        // 获取两小时前的时间点后30分钟的时间点
        LocalDateTime thirtyMinutesAfterTwoHoursAgo = twoHoursAgo.plusMinutes(30);
        return specifiedTime.isAfter(twoHoursAgo) && specifiedTime.isBefore(thirtyMinutesAfterTwoHoursAgo);
    }
    // 判断指定时间是否在当前时间的前30分钟内
    public boolean isNowEnd(LocalDateTime endTime) {
        LocalDateTime thirtyMinutesBefore = LocalDateTime.now().plusMinutes(30);
        return endTime.isBefore(thirtyMinutesBefore) && endTime.isAfter(LocalDateTime.now());
    }
}
